package com.smarthome.service;

import com.alibaba.fastjson.JSONObject;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SmartHomeAgentService {

    // 直接使用具体的聊天模型，而非抽象的ChatClient
    private final OpenAiChatModel chatModel;
    private final DeviceService deviceService;

    @Autowired
    public SmartHomeAgentService(OpenAiChatModel chatModel,
            DeviceService deviceService) {
        this.chatModel = chatModel;
        this.deviceService = deviceService;
    }

    /**
     * 处理用户文本指令
     */
    public String processTextCommand(String userCommand) {
        // 1. 获取当前设备状态
        String deviceStatus = getDeviceStatusSummary();

        // 2. 构建系统提示（使用字符串拼接，避免模板解析错误）
        SystemMessage systemMessage = new SystemMessage("""
                你是智能家居助手，负责处理用户的家居控制指令。
                以下是当前设备状态：
                """ + deviceStatus + """
                        
                请根据用户指令，返回需要执行的操作，格式要求：
                - 只返回JSON格式内容，例如：{"deviceId": "light-1", "action": "turnOn"}
                - action只能是"turnOn"、"turnOff"或"none"（无法识别时）
                - 如果无法识别指令，返回{"action": "none", "message": "原因"}
                """);

        // 3. 构建用户消息
        UserMessage userMessage = new UserMessage(userCommand);

        // 4. 发送请求
        Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
        ChatResponse response = chatModel.call(prompt);

        // 后续处理保持不变...
        return executeDeviceAction(response.getResult()
                .getOutput()
                .getText());
    }

    /**
     * 获取设备状态摘要
     */
    private String getDeviceStatusSummary() {
        return deviceService.getAllDevices()
                .stream()
                .map(device -> String.format(
                        "设备ID: %s, 名称: %s, 类型: %s, 状态: %s",
                        device.getId(), device.getName(), device.getType(), device.isStatus()
                ))
                .collect(Collectors.joining("; "));
    }

    /**
     * 执行设备操作
     */
    private String executeDeviceAction(String aiResponse) {
        try {
            // 这里简化处理，实际项目中应使用JSON解析库（如Jackson）
            if (aiResponse.contains("turnOn")) {
                String deviceId = extractDeviceId(aiResponse);
//                deviceService.turnOn(deviceId);
                return "已打开设备: " + deviceId;
            } else if (aiResponse.contains("turnOff")) {
                String deviceId = extractDeviceId(aiResponse);
//                deviceService.turnOff(deviceId);
                return "已关闭设备: " + deviceId;
            } else if (aiResponse.contains("none")) {
                return "无法执行指令: " + aiResponse;
            }
            return "已执行操作: " + aiResponse;
        } catch (Exception e) {
            return "处理指令时出错: " + e.getMessage();
        }
    }

    /**
     * 从AI响应中提取设备ID（简化实现）
     */
    private String extractDeviceId(String response) {
        response = response.substring(response.indexOf("{"), response.lastIndexOf("}") + 1);
        JSONObject jsonObject = JSONObject.parseObject(response);
        // 实际项目中应使用JSON解析
//        int start = response.indexOf("deviceId") + 10;
//        int end = response.indexOf("\"", start);
        return jsonObject.getString("deviceId");
    }

    public String processTextCommand1(String userCommand) {
        // 1. 获取当前设备状态（例如：空调是否存在、当前状态等）
        String deviceStatus = getDeviceStatusSummary();

        // 2. 构建增强版系统提示（重点：加入意图识别规则和示例）
        SystemMessage systemMessage = new SystemMessage("""
                你是智能家居助手，需要理解用户的显式指令和隐含意图，并生成设备操作。
                            
                ########## 设备状态 ##########
                %s
                            
                ########## 意图识别规则 ##########
                1. 理解用户的隐含需求（例如：
                   - "天太热了" → 隐含需要打开空调（如果有空调设备）
                   - "屋里太黑" → 隐含需要打开灯光（如果有灯设备）
                   - "有点冷" → 隐含需要关闭空调或调高温度
                   - "太吵了" → 隐含需要关闭电视或降低音量
                ）
                2. 必须基于现有设备状态执行操作（没有的设备不返回操作）
                3. 如果无法识别意图或没有对应设备，返回{"action": "none", "message": "原因"}
                            
                ########## 输出格式 ##########
                只返回JSON格式，包含：
                - deviceId：目标设备ID（从设备状态中获取）
                - action：操作类型（turnOn/turnOff/adjust，adjust需额外带参数）
                - （可选）params：调整参数（如温度、亮度等，例如{"temperature": 26}）
                            
                示例：
                - 用户说"天太热了"，且有空调（id:ac-1）→ {"deviceId": "ac-1", "action": "turnOn", "params": {"temperature": 26}}
                - 用户说"关灯"，且客厅灯（id:light-1）开着 → {"deviceId": "light-1", "action": "turnOff"}
                """.formatted(deviceStatus));

        // 3. 构建用户消息
        UserMessage userMessage = new UserMessage(userCommand);

        // 4. 调用大模型
        Prompt prompt = new Prompt(
                List.of(systemMessage, userMessage),
                OpenAiChatOptions.builder()
                        .model("deepseek-v3")
                        .build()
        );
        ChatResponse response = chatModel.call(prompt);

        // 5. 解析响应并执行操作
        String aiResponse = response.getResult()
                .getOutput()
                .getText();
        return executeDeviceAction(aiResponse);
    }

    public String chain(String userInput) {
        String[] systemPrompts = new String[]{"洗菜","切菜","炒菜"};
        String response = userInput;
        for (String prompt : systemPrompts) {
            // 将系统提示与上一个响应结合
            String input = String.format("{%s}\n {%s}", prompt, response);
            Prompt prompt1 = new Prompt(input,
                    OpenAiChatOptions.builder()
                            .model("deepseek-v3")
                            .build()
            );
            // 通过大语言模型处理并捕获输出
            response = chatModel.call(prompt1).getResult().getOutput().getText();
        }
        return response;
    }
}
